﻿/*
	Date:			05/19/2012
	Author:         Fabien Olousouzian
	License:      	Microsoft Public License (Ms-PL)
	Product:        XNA Shader Composer - Project
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Diagnostics;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;

namespace Shader_Composer
{
    /// <summary>
    /// Display the current frame per second
    /// </summary>
    class FPSCounter
    {
        #region Enum

        public enum Position
        {
            UP_LEFT,
            UP_RIGHT,
            DOWN_LEFT,
            DOWN_RIGHT,
            DEBUG,
            NONE
        }

        #endregion

        #region Attributes

        private int _frames;
        private int _framesPerSecond;
        private TimeSpan _elapsedTime;
        private SpriteFont _font;
        private Position _position;
        private Vector2 _dimension;
        private bool _status;

        #endregion

        #region Methods

        /// <summary>
        /// Ctor by default
        /// </summary>
        public FPSCounter()
        {
            _elapsedTime = TimeSpan.Zero;
            _position = Position.NONE;
            _dimension = new Vector2();
            _status = true;
        }

        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="widthWin"></param>
        /// <param name="heightWin"></param>
        public FPSCounter(int widthWin, int heightWin)
        {
            _elapsedTime = TimeSpan.Zero;
            _position = Position.DEBUG;
            _dimension = new Vector2(widthWin, heightWin);
            _status = true;
        }

        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="widthWin"></param>
        /// <param name="heightWin"></param>
        /// <param name="position"></param>
        public FPSCounter(int widthWin, int heightWin, Position position)
        {
            _elapsedTime = TimeSpan.Zero;
            _position = position;
            _dimension = new Vector2(widthWin, heightWin);
            _status = true;
        }

        /// <summary>
        /// Load the font for display
        /// </summary>
        /// <param name="content"></param>
        public void Load(ContentManager content)
        {
            _font = content.Load<SpriteFont>(@"Font\FPSFont");
        }

        /// <summary>
        /// Load the font for display
        /// </summary>
        /// <param name="content"></param>
        /// <param name="fontName"></param>
        public void Load(ContentManager content, string fontName)
        {
            _font = content.Load<SpriteFont>(fontName);
        }

        /// <summary>
        /// Update the frame counter
        /// </summary>
        /// <param name="gameTime"></param>
        public void UpdateFrameRate(GameTime gameTime, ref Device device)
        {
            if (device.keyJustPressed(Keys.H) || device.buttonJustPressed(Buttons.DPadUp))
                 this.Active = !this.Active;
           

            _elapsedTime += gameTime.ElapsedGameTime;

            if (_elapsedTime > TimeSpan.FromSeconds(1))
            {
                _elapsedTime -= TimeSpan.FromSeconds(1);
                _framesPerSecond = _frames;
                _frames = 0;
            }
        }

        /// <summary>
        /// Increment the frame counter
        /// </summary>
        public void IncrementFrameCounter()
        {
            ++_frames;
        }

        /// <summary>
        /// Draw the framerate
        /// Different position is available
        /// </summary>
        /// <param name="spriteBatch"></param>
        public void DrawInfoDebug(ref SpriteBatch spriteBatch)
        {
            if (_position == Position.NONE || !_status)
                return;
            if (_position == Position.DEBUG)
            {
                Debug.WriteLine("FPS : {0}", _framesPerSecond);
                return;
            }

            Vector2 where = new Vector2();

            if (_position == Position.UP_LEFT)
                where = Vector2.Zero;

            if (_position == Position.UP_RIGHT)
                where = new Vector2(_dimension.X - _font.MeasureString(_framesPerSecond.ToString()).X - 10, 0);

            if (_position == Position.DOWN_LEFT)
                where = new Vector2(10, _dimension.Y - _font.MeasureString(_framesPerSecond.ToString()).Y);

            if (_position == Position.DOWN_RIGHT)
                where = new Vector2(_dimension.X - _font.MeasureString(_framesPerSecond.ToString()).X - 10, _dimension.Y - _font.MeasureString(_framesPerSecond.ToString()).Y);

            spriteBatch.Begin();
            if (_framesPerSecond >= 30)
                spriteBatch.DrawString(_font, _framesPerSecond.ToString(), where, Color.YellowGreen);
            else if (_framesPerSecond < 30 && _framesPerSecond > 15)
                spriteBatch.DrawString(_font, _framesPerSecond.ToString(), where, Color.Yellow);
            else
                spriteBatch.DrawString(_font, _framesPerSecond.ToString(), where, Color.Red);
            spriteBatch.End();
        }

        #endregion

        #region Getter & Setter

        /// <summary>
        /// Get the framerate
        /// </summary>
        public int FPS
        {
            get { return _framesPerSecond; }
        }

        /// <summary>
        /// Set the window dimension
        /// </summary>
        public Vector2 WinDimension
        {
            set { _dimension = value; }
        }

        /// <summary>
        /// Get & set the position of framerate display
        /// </summary>
        public Position FPSPosition
        {
            get { return _position; }
            set { _position = value; }
        }

        /// <summary>
        /// Get & set the status counter
        /// </summary>
        public bool Active
        {
            get { return _status; }
            set { _status = value; }
        }

        #endregion
    }
}
